#include "myopenglwidget.h"
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <vtkAxesActor.h>
#include <vtkPointData.h>
#include <vtkUnsignedCharArray.h>
#include <vtkCubeAxesActor.h>
#include <vtkProperty.h>
#include <vtkPlaneSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCaptionActor2D.h>     // vtkCaptionActor2D 类定义（X/Y/Z 轴标签的基础类）
#include <vtkTextMapper.h>
#include <QMouseEvent>
#include <QDebug>

// 颜色映射函数，这里使用简单的热力图作为示例
void colorMapRainbow(float t, unsigned char& r, unsigned char& g, unsigned char& b) {
    // Rainbow color mapping
    float h = (1.0f - t) * 5.0f / 3.0f;
    int i = static_cast<int>(floor(h));
    float f = h - i;
    float q = 1.0f - f;
    switch (i) {
    case 0: r = 255; g = static_cast<unsigned char>(255 * q); b = 0; break;
    case 1: r = static_cast<unsigned char>(255 * q); g = 255; b = 0; break;
    case 2: r = 0; g = 255; b = static_cast<unsigned char>(255 * f); break;
    case 3: r = 0; g = static_cast<unsigned char>(255 * q); b = 255; break;
    case 4: r = static_cast<unsigned char>(255 * f); g = 0; b = 255; break;
    default: r = 255; g = 0; b = static_cast<unsigned char>(255 * q); break;
    }
}

// 始终返回绿色
void greenMapRainbow(float t, unsigned char& r, unsigned char& g, unsigned char& b) {
    // Rainbow color mapping
   // 忽略 value 参数，始终返回绿色
    r = 0;
    g = 255;
    b = 0;
}

void MyOpenGLWidget::setColorByField(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& cloud, const std::string& field)
{
    float minVal = std::numeric_limits<float>::max();
    float maxVal = std::numeric_limits<float>::lowest();

    // Find the min and max values for the specified field
    for (const auto& point : cloud->points) {
        float val;
        if (field == "x") val = point.x;
        else if (field == "y") val = point.y;
        else if (field == "z") val = point.z;
        else {
            qDebug() << "Unsupported field name:" << QString::fromStdString(field);
            return;
        }
        minVal = std::min(minVal, val);
        maxVal = std::max(maxVal, val);
    }

    float range = maxVal - minVal;
    if (range == 0.0f) range = 1.0f;  // 防止除以 0

    // 复用已有的 points 和 colors
    points->Reset();
    colors->Reset();

    for (const auto& point : cloud->points) {
        float val;
        if (field == "x") val = point.x;
        else if (field == "y") val = point.y;
        else if (field == "z") val = point.z;

        float normalizedValue = (val - minVal) / range;

        unsigned char r, g, b;
        greenMapRainbow(normalizedValue, r, g, b);

        points->InsertNextPoint(point.x, point.y, point.z);
        colors->InsertNextTuple3(r, g, b);
    }

    // 更新 polydata 的数据（不需要重新 SetPoints/SetScalars）
    polydata->Modified();  // 告诉 VTK 数据已经改变
}

MyOpenGLWidget::MyOpenGLWidget(QWidget* parent) : QVTKOpenGLNativeWidget(parent)
{
    setupVTKPipeline();
    picker = vtkSmartPointer<vtkPointPicker>::New();
    picker->SetTolerance(0.001);
}

void MyOpenGLWidget::setupVTKPipeline()
{
    //m_renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();

    // 初始化 VTK 组件
    points = vtkSmartPointer<vtkPoints>::New();
    polydata = vtkSmartPointer<vtkPolyData>::New();
    vertices = vtkSmartPointer<vtkCellArray>::New();
    mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    actor = vtkSmartPointer<vtkActor>::New();
    m_renderer = vtkSmartPointer<vtkRenderer>::New();
    initAxesSet();

    // 配置颜色数组
    colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
    colors->SetNumberOfComponents(3);
    colors->SetName("colors");
    polydata->SetPoints(points);
    polydata->GetPointData()->SetScalars(colors);
    actor->SetMapper(mapper);

    // 配置渲染器和窗口
    m_renderWindow = this->renderWindow();
    m_renderer->SetBackground(0.1, 0.2, 0.3);

    // 创建并配置文本演员
    m_textActor = vtkSmartPointer<vtkTextActor>::New();
    m_textActor->GetTextProperty()->SetColor(1.0, 1.0, 1.0);
    m_textActor->GetTextProperty()->SetFontFamilyToArial();
    m_textActor->GetTextProperty()->SetFontSize(12);
    m_textActor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();
    m_textActor->GetPositionCoordinate()->SetValue(0.02, 0.02);

    // 添加 Actor 到渲染器
    m_renderer->AddActor(axesActor);
    m_renderer->AddActor(actor);
    m_renderer->AddActor2D(m_textActor);

    // 重置相机
    m_renderer->ResetCamera();

    // 将渲染器添加到渲染窗口
    renderWindow()->AddRenderer(m_renderer);
}

void MyOpenGLWidget::initAxesSet()
{
    // 创建坐标轴 Actor
    axesActor = vtkSmartPointer<vtkAxesActor>::New();
    axesActor->SetTotalLength(0.1, 0.1, 0.1);  // 增大坐标轴长度

    // 设置 X 轴标签的字体大小
    xCaption = axesActor->GetXAxisCaptionActor2D();
    xCaption->GetTextActor()->SetTextScaleModeToViewport();
    if (xCaption)
    {
        textXProp = xCaption->GetCaptionTextProperty();
        if (textXProp)
        {
            textXProp->SetFontSize(5);
            textXProp->SetColor(1.0, 1.0, 0.0);
        }
    }

    // 设置 Y 轴标签的字体大小（可选）
    yCaption = axesActor->GetYAxisCaptionActor2D();
    yCaption->GetTextActor()->SetTextScaleModeToViewport();
    if (yCaption)
    {
        textYProp = yCaption->GetCaptionTextProperty();
        if (textYProp)
        {
            textYProp->SetFontSize(5);
            textYProp->SetColor(1.0, 1.0, 0.0);
        }
    }
    zCaption = axesActor->GetZAxisCaptionActor2D();
    // 设置 Z 轴标签的字体大小（可选）
    zCaption->GetTextActor()->SetTextScaleModeToViewport();
    if (zCaption)
    {
        textZProp = zCaption->GetCaptionTextProperty();
        if (textZProp)
        {
            textZProp->SetFontSize(5);
            textZProp->SetColor(0.0, 0.0, 0.0);
        }
    }
}

void MyOpenGLWidget::updatePointCloud(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& cloud)
{
    if (!cloud) return;
    setColorByField(cloud, "x");  // 根据 x 值上色

    vertices->Reset(); // 清除旧的顶点信息
    for (vtkIdType i = 0; i < points->GetNumberOfPoints(); ++i) {
        vertices->InsertNextCell(1, &i); // 插入新的顶点信息
    }
    polydata->SetVerts(vertices); // 更新 polydata 的顶点集

    // 重要：确保 mapper 知道它需要重新获取数据
    mapper->SetInputData(polydata);

    this->renderWindow()->Render(); // 刷新显示
}

void MyOpenGLWidget::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton) {
        int x = event->x();
        int y = this->height() - event->y(); // VTK 使用不同的坐标系

        if (picker->Pick(x, y, 0, m_renderer)) {
            double pos[3];
            picker->GetPickPosition(pos);
            QString text = QString("Selected Point: (%1, %2, %3)").arg(pos[0]).arg(pos[1]).arg(pos[2]);
            m_textActor->SetInput(text.toStdString().c_str());
            this->renderWindow()->Render();
        }
    }
    QVTKOpenGLNativeWidget::mousePressEvent(event);
}